//! # c19_tuple_basics - 元组入门：多个值的组合
//! 
//! 本案例全面介绍Rust中元组(Tuple)的基础知识和使用方法
//! 包括元组的创建、访问、解构、嵌套以及实际应用场景

fn main() {
    println!("=== Rust 元组(Tuple)基础详解 ===\n");

    // 1. 元组概述
    tuple_overview();

    // 2. 元组的创建和声明
    tuple_creation();

    // 3. 元组元素访问
    tuple_access();

    // 4. 元组类型和混合数据类型
    tuple_types();

    // 5. 元组解构(Destructuring)
    tuple_destructuring();

    // 6. 单元元组和空元组
    unit_and_empty_tuples();

    // 7. 嵌套元组
    nested_tuples();

    // 8. 元组作为函数参数和返回值
    tuples_in_functions();

    // 9. 元组的比较和相等性
    tuple_comparison();

    // 10. 元组的实际应用场景
    practical_applications();

    println!("\n=== 元组基础学习完成！===");
}

/// 1. 元组概述
/// 介绍元组的基本概念和特性
fn tuple_overview() {
    println!("1. 元组概述");
    println!("   元组是一种将多个不同类型的值组合成一个复合类型的方式");
    println!("   元组具有固定长度，一旦声明，其长度不能增长或缩减");
    println!("   元组可以包含不同类型的数据，这是与数组的主要区别");
    
    println!("\n1.1 元组的基本特性");
    println!("   - 固定长度：编译时确定长度，运行时不可变");
    println!("   - 有序集合：元素有明确的顺序和位置");
    println!("   - 类型多样：可包含不同类型的元素");
    println!("   - 零成本抽象：运行时没有额外开销");
    println!("   - 栈分配：通常在栈上分配内存");
    
    println!("\n1.2 元组与其他数据结构的区别");
    println!("   元组 vs 数组：");
    println!("   - 元组可包含不同类型，数组必须同类型");
    println!("   - 元组长度固定，数组长度也固定但类型统一");
    println!("   - 元组通过索引访问，数组也通过索引访问");
    
    println!("   元组 vs 结构体：");
    println!("   - 元组元素通过位置标识，结构体通过字段名");
    println!("   - 元组更适合临时组合，结构体更适合正式建模");
    println!("   - 元组语法简洁，结构体语义更明确");
    println!();
}

/// 2. 元组的创建和声明
/// 展示各种创建和声明元组的方法
fn tuple_creation() {
    println!("2. 元组的创建和声明");
    
    println!("2.1 基本创建语法");
    // 最简单的元组创建方式
    let simple_tuple = (1, 2, 3);
    println!("   简单数字元组: {:?}", simple_tuple);
    
    // 混合类型元组
    let mixed_tuple = (42, "hello", 3.14, true);
    println!("   混合类型元组: {:?}", mixed_tuple);
    
    // 显式类型注解
    let typed_tuple: (i32, f64, bool) = (10, 2.5, false);
    println!("   显式类型注解: {:?}", typed_tuple);
    
    println!("\n2.2 不同长度的元组");
    // 单元素元组（注意逗号！）
    let single_tuple = (42,);  // 注意：单元素元组必须有逗号
    println!("   单元素元组: {:?}", single_tuple);
    
    // 双元素元组（二元组）
    let pair = (10, 20);
    println!("   二元组: {:?}", pair);
    
    // 三元素元组（三元组）
    let triple = (1, "two", 3.0);
    println!("   三元组: {:?}", triple);
    
    // 更长的元组
    let long_tuple = (1, 2, 3, 4, 5, 6, 7, 8);
    println!("   长元组: {:?}", long_tuple);
    
    println!("\n2.3 特殊的元组");
    // 空元组（单元类型）
    let empty_tuple = ();
    println!("   空元组(单元类型): {:?}", empty_tuple);
    
    // 包含引用的元组
    let reference_tuple = (&42, &"hello");
    println!("   引用元组: {:?}", reference_tuple);
    
    // 可变元组（元组本身不可变，但可以重新赋值）
    let mut mutable_tuple = (1, 2);
    println!("   初始可变元组: {:?}", mutable_tuple);
    mutable_tuple = (3, 4);  // 重新赋值
    println!("   重新赋值后: {:?}", mutable_tuple);
    println!();
}

/// 3. 元组元素访问
/// 展示访问元组元素的各种方法
fn tuple_access() {
    println!("3. 元组元素访问");
    
    println!("3.1 索引访问");
    let coordinates = (100, 200, 300);
    // 使用点号和索引访问元素
    println!("   坐标元组: {:?}", coordinates);
    println!("   x坐标 (索引0): {}", coordinates.0);
    println!("   y坐标 (索引1): {}", coordinates.1);
    println!("   z坐标 (索引2): {}", coordinates.2);
    
    println!("\n3.2 复杂类型的访问");
    let complex_tuple = ("用户001", 25, true, vec![1, 2, 3]);
    println!("   复杂元组: {:?}", complex_tuple);
    println!("   用户名: {}", complex_tuple.0);
    println!("   年龄: {}", complex_tuple.1);
    println!("   活跃状态: {}", complex_tuple.2);
    println!("   数据: {:?}", complex_tuple.3);
    
    println!("\n3.3 嵌套访问");
    let nested = ((1, 2), (3, 4));
    println!("   嵌套元组: {:?}", nested);
    println!("   第一个子元组: {:?}", nested.0);
    println!("   第二个子元组: {:?}", nested.1);
    println!("   嵌套访问 nested.0.0: {}", nested.0.0);
    println!("   嵌套访问 nested.0.1: {}", nested.0.1);
    println!("   嵌套访问 nested.1.0: {}", nested.1.0);
    println!("   嵌套访问 nested.1.1: {}", nested.1.1);
    
    println!("\n3.4 访问限制说明");
    println!("   注意：元组索引必须是编译时常量");
    println!("   错误示例：let i = 0; coordinates.i  // 编译错误");
    println!("   正确示例：coordinates.0  // 编译通过");
    println!();
}

/// 4. 元组类型和混合数据类型
/// 展示元组的类型系统和多样化数据组合
fn tuple_types() {
    println!("4. 元组类型和混合数据类型");
    
    println!("4.1 类型签名");
    let int_tuple: (i32, i32) = (10, 20);
    let mixed_tuple: (i32, &str, f64, bool) = (42, "hello", 3.14, true);
    let reference_tuple: (&i32, &str) = (&100, &"world");
    
    println!("   整数元组类型 (i32, i32): {:?}", int_tuple);
    println!("   混合类型 (i32, &str, f64, bool): {:?}", mixed_tuple);
    println!("   引用元组类型 (&i32, &str): {:?}", reference_tuple);
    
    println!("\n4.2 不同数据类型的组合示例");
    
    // 基础数据类型组合
    let basic_types = (
        42_i32,           // 32位有符号整数
        3.14_f64,         // 64位浮点数
        'A',              // 字符
        true,             // 布尔值
        "hello"           // 字符串字面量(&str)
    );
    println!("   基础类型组合: {:?}", basic_types);
    
    // 集合类型组合
    let collection_types = (
        vec![1, 2, 3],              // 向量
        [4, 5, 6],                  // 数组
        "rust".to_string(),         // String类型
    );
    println!("   集合类型组合: {:?}", collection_types);
    
    // 选项类型组合
    let option_types = (
        Some(42),          // Option<i32>
        None::<String>,    // Option<String>
        Ok::<i32, &str>(100),     // Result<i32, &str>
        Err::<i32, &str>("error") // Result<i32, &str>
    );
    println!("   选项类型组合: {:?}", option_types);
    
    println!("\n4.3 类型推导示例");
    // 编译器可以推导出类型
    let auto_inferred = (1, 2.0, "three");
    // 等价于: let auto_inferred: (i32, f64, &str) = (1, 2.0, "three");
    println!("   自动推导类型: {:?}", auto_inferred);
    
    println!("\n4.4 元组的类型兼容性");
    println!("   相同结构的元组类型兼容:");
    let tuple_a: (i32, bool) = (1, true);
    let tuple_b: (i32, bool) = (2, false);
    println!("   tuple_a: {:?}", tuple_a);
    println!("   tuple_b: {:?}", tuple_b);
    println!("   两个元组类型相同，可以相互赋值");
    println!();
}

/// 5. 元组解构(Destructuring)
/// 展示元组解构的各种模式和用法
fn tuple_destructuring() {
    println!("5. 元组解构(Destructuring)");
    
    println!("5.1 基本解构");
    let point = (3, 4);
    let (x, y) = point;  // 解构赋值
    println!("   原始点: {:?}", point);
    println!("   解构后 x = {}, y = {}", x, y);
    
    println!("\n5.2 多类型解构");
    let user_info = ("Alice", 30, true);
    let (name, age, is_active) = user_info;
    println!("   用户信息: {:?}", user_info);
    println!("   解构: 姓名={}, 年龄={}, 活跃={}", name, age, is_active);
    
    println!("\n5.3 部分解构 - 使用下划线忽略");
    let coordinates = (10, 20, 30);
    let (x, _, z) = coordinates;  // 忽略y坐标
    println!("   3D坐标: {:?}", coordinates);
    println!("   只关心 x={}, z={}, 忽略y", x, z);
    
    println!("\n5.4 嵌套解构");
    let nested_data = ((1, 2), (3, 4));
    let ((a, b), (c, d)) = nested_data;
    println!("   嵌套数据: {:?}", nested_data);
    println!("   嵌套解构: a={}, b={}, c={}, d={}", a, b, c, d);
    
    println!("\n5.5 在函数参数中解构");
    fn process_point((x, y): (i32, i32)) -> i32 {
        println!("     函数内解构: x={}, y={}", x, y);
        x + y
    }
    
    let point = (5, 7);
    let sum = process_point(point);
    println!("   传入点 {:?}, 计算结果: {}", point, sum);
    
    println!("\n5.6 在let语句中的模式匹配");
    let complex_tuple = (1, (2, 3), 4);
    match complex_tuple {
        (a, (b, c), d) => {
            println!("   模式匹配解构: a={}, b={}, c={}, d={}", a, b, c, d);
        }
    }
    
    println!("\n5.7 解构和可变性");
    let mut_tuple = (10, 20);
    let (mut x, y) = mut_tuple;  // x是可变的，y是不可变的
    println!("   原始: x={}, y={}", x, y);
    x += 5;
    println!("   修改x后: x={}, y={}", x, y);
    println!();
}

/// 6. 单元元组和空元组
/// 探讨特殊的元组类型
fn unit_and_empty_tuples() {
    println!("6. 单元元组和空元组");
    
    println!("6.1 单元类型 ()");
    let unit = ();
    println!("   单元类型值: {:?}", unit);
    println!("   单元类型大小: {} bytes", std::mem::size_of_val(&unit));
    
    // 单元类型常用于表示"无返回值"
    fn do_something() {
        println!("     执行某些操作...");
        // 隐式返回 ()
    }
    
    let result = do_something();
    println!("   函数返回的单元类型: {:?}", result);
    
    println!("\n6.2 单元素元组");
    let single = (42,);  // 注意逗号！
    println!("   单元素元组: {:?}", single);
    println!("   访问单一元素: {}", single.0);
    
    // 比较：没有逗号的不是元组
    let not_tuple = (42);  // 这只是括号中的整数，不是元组
    println!("   不是元组(只是括号): {}", not_tuple);
    
    println!("\n6.3 单元类型的应用场景");
    println!("   - 表示无返回值的函数");
    println!("   - 作为泛型的占位符");
    println!("   - 表示操作成功但无数据");
    
    // 示例：使用单元类型表示操作结果
    fn operation_success() -> Result<(), &'static str> {
        // 模拟操作
        if true {
            Ok(())  // 成功但无返回数据
        } else {
            Err("操作失败")
        }
    }
    
    match operation_success() {
        Ok(()) => println!("   操作成功！"),
        Err(e) => println!("   操作失败: {}", e),
    }
    println!();
}

/// 7. 嵌套元组
/// 展示元组的嵌套使用和复杂结构
fn nested_tuples() {
    println!("7. 嵌套元组");
    
    println!("7.1 二级嵌套");
    let nested = ((1, 2), (3, 4));
    println!("   二级嵌套: {:?}", nested);
    println!("   访问: nested.0 = {:?}, nested.1 = {:?}", nested.0, nested.1);
    println!("   深层访问: nested.0.0 = {}", nested.0.0);
    
    println!("\n7.2 多级嵌套");
    let deep_nested = (((1, 2), 3), ((4, 5), 6));
    println!("   多级嵌套: {:?}", deep_nested);
    println!("   深层访问: deep_nested.0.0.0 = {}", deep_nested.0.0.0);
    println!("   深层访问: deep_nested.1.0.1 = {}", deep_nested.1.0.1);
    
    println!("\n7.3 混合嵌套类型");
    let mixed_nested = (
        (1, "hello"),           // (i32, &str)
        (3.14, true, 'A'),      // (f64, bool, char)
        vec![1, 2, 3]           // Vec<i32>
    );
    println!("   混合嵌套: {:?}", mixed_nested);
    println!("   第一部分: {:?}", mixed_nested.0);
    println!("   第二部分: {:?}", mixed_nested.1);
    println!("   第三部分: {:?}", mixed_nested.2);
    
    println!("\n7.4 嵌套元组的解构");
    let coordinates_3d = ((10, 20), 30);
    let ((x, y), z) = coordinates_3d;
    println!("   3D坐标嵌套: {:?}", coordinates_3d);
    println!("   解构结果: x={}, y={}, z={}", x, y, z);
    
    println!("\n7.5 复杂嵌套示例：树状结构");
    type Point2D = (i32, i32);
    type Rectangle = (Point2D, Point2D);  // 左上角和右下角
    
    let rect: Rectangle = ((0, 0), (100, 50));
    println!("   矩形定义: {:?}", rect);
    let ((left, top), (right, bottom)) = rect;
    println!("   矩形解构: 左={}，顶={}，右={}，底={}", left, top, right, bottom);
    
    println!("\n7.6 嵌套深度的性能考虑");
    println!("   - 嵌套过深影响代码可读性");
    println!("   - 深度嵌套的访问语法复杂");
    println!("   - 建议超过3级嵌套时考虑使用结构体");
    println!();
}

/// 8. 元组作为函数参数和返回值
/// 展示元组在函数中的应用
fn tuples_in_functions() {
    println!("8. 元组作为函数参数和返回值");
    
    println!("8.1 元组作为函数参数");
    
    // 接受元组参数的函数
    fn calculate_distance(point1: (f64, f64), point2: (f64, f64)) -> f64 {
        let (x1, y1) = point1;
        let (x2, y2) = point2;
        ((x2 - x1).powi(2) + (y2 - y1).powi(2)).sqrt()
    }
    
    let p1 = (0.0, 0.0);
    let p2 = (3.0, 4.0);
    let distance = calculate_distance(p1, p2);
    println!("   点 {:?} 到点 {:?} 的距离: {:.2}", p1, p2, distance);
    
    println!("\n8.2 元组作为返回值");
    
    // 返回多个值的函数
    fn get_name_and_age() -> (String, u32) {
        ("张三".to_string(), 25)
    }
    
    let user_data = get_name_and_age();
    println!("   获取用户数据: {:?}", user_data);
    
    // 同时解构返回值
    let (name, age) = get_name_and_age();
    println!("   解构获取: 姓名={}, 年龄={}", name, age);
    
    println!("\n8.3 返回计算结果和元数据");
    
    fn divide_with_info(a: f64, b: f64) -> (f64, bool, String) {
        if b == 0.0 {
            (0.0, false, "除零错误".to_string())
        } else {
            let result = a / b;
            let success = true;
            let message = format!("{} ÷ {} = {}", a, b, result);
            (result, success, message)
        }
    }
    
    let (result, success, message) = divide_with_info(10.0, 3.0);
    println!("   计算结果: {}", result);
    println!("   是否成功: {}", success);
    println!("   消息: {}", message);
    
    println!("\n8.4 元组参数的解构");
    
    fn print_point((x, y): (i32, i32)) {
        println!("     点的坐标: x={}, y={}", x, y);
    }
    
    print_point((5, 10));
    
    println!("\n8.5 返回不同长度的元组");
    
    fn get_rgb() -> (u8, u8, u8) {
        (255, 128, 0)  // 橙色
    }
    
    fn get_rgba() -> (u8, u8, u8, u8) {
        (255, 128, 0, 200)  // 橙色 + 透明度
    }
    
    let rgb = get_rgb();
    let rgba = get_rgba();
    println!("   RGB颜色: {:?}", rgb);
    println!("   RGBA颜色: {:?}", rgba);
    
    println!("\n8.6 高阶函数与元组");
    
    let points = vec![(1, 2), (3, 4), (5, 6)];
    let sum_points: Vec<i32> = points
        .iter()
        .map(|(x, y)| x + y)  // 在闭包中解构元组
        .collect();
    
    println!("   原始点集: {:?}", points);
    println!("   坐标和: {:?}", sum_points);
    println!();
}

/// 9. 元组的比较和相等性
/// 展示元组的比较操作
fn tuple_comparison() {
    println!("9. 元组的比较和相等性");
    
    println!("9.1 相等性比较");
    let tuple1 = (1, 2, 3);
    let tuple2 = (1, 2, 3);
    let tuple3 = (1, 2, 4);
    
    println!("   tuple1: {:?}", tuple1);
    println!("   tuple2: {:?}", tuple2);
    println!("   tuple3: {:?}", tuple3);
    println!("   tuple1 == tuple2: {}", tuple1 == tuple2);
    println!("   tuple1 == tuple3: {}", tuple1 == tuple3);
    println!("   tuple1 != tuple3: {}", tuple1 != tuple3);
    
    println!("\n9.2 字典序比较");
    let a = (1, 2);
    let b = (1, 3);
    let c = (2, 1);
    
    println!("   元组 a: {:?}", a);
    println!("   元组 b: {:?}", b);
    println!("   元组 c: {:?}", c);
    println!("   a < b: {} (第二个元素2 < 3)", a < b);
    println!("   a < c: {} (第一个元素1 < 2)", a < c);
    println!("   b > a: {}", b > a);
    
    println!("\n9.3 混合类型比较");
    let mixed1 = (1, "apple");
    let mixed2 = (1, "banana");
    let mixed3 = (2, "apple");
    
    println!("   mixed1: {:?}", mixed1);
    println!("   mixed2: {:?}", mixed2);
    println!("   mixed3: {:?}", mixed3);
    println!("   mixed1 < mixed2: {} ('apple' < 'banana')", mixed1 < mixed2);
    println!("   mixed1 < mixed3: {} (1 < 2)", mixed1 < mixed3);
    
    println!("\n9.4 元组排序");
    let mut tuples = vec![(3, "c"), (1, "a"), (2, "b"), (1, "z")];
    println!("   排序前: {:?}", tuples);
    
    tuples.sort();  // 使用默认的字典序排序
    println!("   排序后: {:?}", tuples);
    
    println!("\n9.5 比较的限制");
    println!("   注意：只有当元组中所有元素类型都实现了相应trait时，");
    println!("   元组才能进行比较操作：");
    println!("   - 相等比较需要 PartialEq trait");
    println!("   - 大小比较需要 PartialOrd trait");
    println!("   - 完全排序需要 Ord trait");
    println!();
}

/// 10. 元组的实际应用场景
/// 展示元组在实际编程中的应用
fn practical_applications() {
    println!("10. 元组的实际应用场景");
    
    println!("10.1 坐标和几何计算");
    type Point2D = (f64, f64);
    type Point3D = (f64, f64, f64);
    
    let origin: Point2D = (0.0, 0.0);
    let point_2d: Point2D = (3.0, 4.0);
    let point_3d: Point3D = (1.0, 2.0, 3.0);
    
    println!("    2D坐标系统:");
    println!("    原点: {:?}", origin);
    println!("    点: {:?}", point_2d);
    println!("    3D点: {:?}", point_3d);
    
    // 计算2D距离
    fn distance_2d(p1: Point2D, p2: Point2D) -> f64 {
        let (x1, y1) = p1;
        let (x2, y2) = p2;
        ((x2-x1).powi(2) + (y2-y1).powi(2)).sqrt()
    }
    
    println!("    距离: {:.2}", distance_2d(origin, point_2d));
    
    println!("\n10.2 键值对和映射");
    let key_value_pairs = vec![
        ("name", "Alice"),
        ("age", "30"), 
        ("city", "Beijing")
    ];
    
    println!("    键值对列表:");
    for (key, value) in &key_value_pairs {
        println!("    {} -> {}", key, value);
    }
    
    println!("\n10.3 函数返回多个值");
    
    // 字符串分析函数
    fn analyze_string(s: &str) -> (usize, usize, usize) {
        let char_count = s.chars().count();
        let word_count = s.split_whitespace().count();
        let byte_count = s.len();
        (char_count, word_count, byte_count)
    }
    
    let text = "Hello Rust World";
    let (chars, words, bytes) = analyze_string(text);
    println!("    文本分析 '{}':", text);
    println!("    字符数: {}, 单词数: {}, 字节数: {}", chars, words, bytes);
    
    println!("\n10.4 错误处理和状态返回");
    
    fn parse_coordinates(input: &str) -> Result<(f64, f64), String> {
        let parts: Vec<&str> = input.split(',').collect();
        if parts.len() != 2 {
            return Err("需要恰好两个坐标值".to_string());
        }
        
        let x = parts[0].trim().parse::<f64>()
            .map_err(|_| "无法解析x坐标".to_string())?;
        let y = parts[1].trim().parse::<f64>()
            .map_err(|_| "无法解析y坐标".to_string())?;
        
        Ok((x, y))
    }
    
    let input1 = "3.5, 4.2";
    let input2 = "invalid, input";
    
    match parse_coordinates(input1) {
        Ok((x, y)) => println!("    解析成功: ({}, {})", x, y),
        Err(e) => println!("    解析失败: {}", e),
    }
    
    match parse_coordinates(input2) {
        Ok((x, y)) => println!("    解析成功: ({}, {})", x, y),
        Err(e) => println!("    解析失败: {}", e),
    }
    
    println!("\n10.5 数据库查询结果");
    // 模拟数据库查询返回多个字段
    fn query_user(user_id: u32) -> Option<(String, u32, String, bool)> {
        // 模拟查询
        if user_id == 1 {
            Some(("Alice".to_string(), 25, "alice@example.com".to_string(), true))
        } else {
            None
        }
    }
    
    match query_user(1) {
        Some((name, age, email, active)) => {
            println!("    用户查询结果:");
            println!("    姓名: {}, 年龄: {}, 邮箱: {}, 活跃: {}", name, age, email, active);
        }
        None => println!("    未找到用户"),
    }
    
    println!("\n10.6 配置和设置");
    // 使用元组存储配置信息
    type DatabaseConfig = (String, u16, String, String);  // (host, port, username, password)
    type ServerConfig = (String, u16, bool);  // (bind_address, port, debug_mode)
    
    let db_config: DatabaseConfig = ("localhost".to_string(), 5432, "user".to_string(), "pass".to_string());
    let server_config: ServerConfig = ("0.0.0.0".to_string(), 8080, true);
    
    println!("    数据库配置: {:?}", db_config);
    println!("    服务器配置: {:?}", server_config);
    
    println!("\n10.7 元组的最佳实践建议");
    println!("    - 元素少于4个时优先使用元组");
    println!("    - 元素语义明确时考虑使用结构体");
    println!("    - 临时数据组合时元组更简洁");
    println!("    - 需要字段名时使用结构体");
    println!("    - 函数返回多个值时元组很有用");
    println!("    - 复杂嵌套时考虑重构为结构体");
    println!();
}
